package com.java.forum.d_controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.java.forum.a_entity.Message;
import com.java.forum.c_service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@RestController
public class WebsocketController implements WebSocketHandler {
    //concurrent包的线程安全map，用来存放每个客户端对应的MyWebSocket对象。
    private static final ConcurrentHashMap<Integer, WebSocketSession> webSocket = new ConcurrentHashMap<>();

    private static final ObjectMapper objectMapper = new ObjectMapper();

    private MessageService messageService;

    @Autowired
    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }

    //连接成功后
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws IOException {
        String uid = session.getAttributes().get("uid").toString();
        webSocket.put(Integer.parseInt(uid), session);//加入map中
        onlineCount();
        //登录之后获取所有未读消息
        List<Message> messages = messageService.getUnreadMessage(Integer.parseInt(uid));
        for (Message m : messages) {
            session.sendMessage(encode(m));
//            messageService.readMessage(m.getMid());
        }
    }


    //接收来自客户端的消息
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
        if (message instanceof TextMessage) {
            Message m;
            try {
                m = decode(message);
                m.setSendDate(new Date());
//                messageService.storeMessage(m);
//                sendToUser(m);
//                session.sendMessage(encode(m));//向发送用户返回message
                if (m.getType() == 1 || m.getType() == 2) {
                    m.setIsRead(0);
                    m = messageService.storeMessage(m);
                    sendToUser(m);
                    session.sendMessage(encode(m));
                } else if (m.getType() == -2) {
                    confirmFriendMessage(m);
                } else if (m.getType() == -1) {
                    sendToUser(m);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    public void confirmFriendMessage(Message m) {
        messageService.readMessage(Integer.parseInt(m.getData()));//设为已读
    }

    public void sendToUser(Message m) throws IOException {
        Integer to = m.getTo();
        WebSocketSession session = webSocket.get(to);
        //用户在线
        if (session != null) {
            session.sendMessage(encode(m));
//            messageService.readMessage(m.getMid());//发送成功,设为已读
        }
    }

    //将textMessage中的getPayload()返回值转换成Message对象
    public Message decode(WebSocketMessage<?> Message) throws JsonProcessingException {
        return objectMapper.readValue(Message.getPayload().toString(), Message.class);
    }

    //将Message对象转换成String
    public WebSocketMessage<?> encode(Message Message) throws JsonProcessingException {
        return new TextMessage(objectMapper.writeValueAsString(Message));
    }

    //发生错误
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) {
        exception.printStackTrace();
//        String uid = session.getAttributes().get("uid").toString();
//        WebSocketSession s = webSocket.remove(Integer.parseInt(uid));
//        try {
//            if (s != null)
//                s.close();
//        } catch (Exception ignored) {
//        }
//        onlineCount();
    }

    //关闭连接之后
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
        String uid = session.getAttributes().get("uid").toString();
        WebSocketSession s = webSocket.remove(Integer.parseInt(uid));
        try {
            if (s != null)
                s.close();
        } catch (IOException ignored) {
        }
        onlineCount();
    }

    @Override
    public boolean supportsPartialMessages() {
        return true;
    }


    public static void onlineCount() {
        System.out.println("当前用户在线:" + webSocket.size());
    }
}
